package mattypserver.dyndns.org.oah.impl;

import java.net.URLEncoder;

import mattypserver.dyndns.org.oah.AbstractOAuthHelper;
import mattypserver.dyndns.org.oah.OAuthAccessToken;
import mattypserver.dyndns.org.oah.OAuthRequestToken;
import mattypserver.dyndns.org.oah.OAuthVerifier;
import oauth.signpost.OAuth;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthProvider;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;

public class BasicOAuthHelper extends AbstractOAuthHelper {

	public static final String OAUTH_TOKEN_PARAM = "oauth_token";
	public static final String OAUTH_VERIFIER_PARAM = "oauth_verifier";
	public static final String TAG = "BasicOAuthHelper";

	public BasicOAuthHelper() {
		Log.d(TAG, "Default Constructor invoked");
	}

	public BasicOAuthHelper(String cKey, String cSecret, String rTokenUrl,
			String accessTokenUrl, String authTokenUrl, String callBackUrl){
		Log.d(TAG, "Parameterized Constructor Invoked");
		this.setup(cKey, cSecret, rTokenUrl, accessTokenUrl,
				authTokenUrl, callBackUrl);
	}

	
	public void setup(String cKey, String cSecret, String rTokenUrl,
			String accessTokenUrl, String authTokenUrl, String callBackUrl) {
		Log.d(TAG, "Setup Invoked");
		Log.d(TAG, "Setup Params: [" + cKey + ", " + cSecret + ", " + rTokenUrl
				+ ", " + accessTokenUrl + ", " + authTokenUrl + ", "
				+ callBackUrl + "]");

		setOAuthConsumer(new CommonsHttpOAuthConsumer(cKey, cSecret));
		setOAuthProvider(new CommonsHttpOAuthProvider(rTokenUrl,
				accessTokenUrl, authTokenUrl));
		setCallBackUrl(callBackUrl.equals(null) ? OAuth.OUT_OF_BAND
				: callBackUrl);
		getOAuthProvider().setOAuth10a(true);

	}

	public void retrieveOAuthVerifier(Intent i) {
		Log.d(TAG, "retrive verifier invoked");
		
		Uri uri = i.getData();
		
		if(uri != null) {
			Log.d(TAG, "URI: [" + uri.toString() + "]");
			String token = uri.getQueryParameter(OAUTH_TOKEN_PARAM);
			String verifier = uri.getQueryParameter(OAUTH_VERIFIER_PARAM);
			Log.d(TAG, "Verifier Received: [" + token + ", " + verifier + "]");
			setOAuthVerifier(new OAuthVerifier(token, verifier));
		}else{
			Log.d(TAG, "Null URI");
			setOAuthVerifier(null);
		}

	}

	public void retrieveRequestToken() {
		try {
			Log.d(TAG, "Request Endpoint Url: [" + getOAuthProvider().getRequestTokenEndpointUrl() + "]");
			Log.d(TAG, "Callback Url: [" + getCallBackUrl() + "]");
			setRequestToken(new OAuthRequestToken(getOAuthProvider()
					.retrieveRequestToken(getOAuthConsumer(), getCallBackUrl())));
			Log.d(TAG, "Request Token received: " + getRequestToken().getRequestToken());
		} catch (Exception e) {
			Log.e(TAG, e.getMessage());
		}
	}

	public void retrieveAccessToken() {
		try {		
			if(getVerifier() != null){
				Log.d(TAG, "Retrieving Access Token with verifier");
				Log.d(TAG, "verifying token: [" + getVerifier().getvToken() + "]");
				Log.d(TAG, "Provider check: [" + getOAuthProvider().getAccessTokenEndpointUrl() + "]");
				Log.d(TAG, "Consumer check: [" + getOAuthConsumer().getConsumerKey() + "]");
				Log.d(TAG, "Urlencoded vtoken: [" + URLEncoder.encode(getVerifier().getVerifier(), "UTF-8") + "]");
				
				getOAuthProvider().retrieveAccessToken(getOAuthConsumer(),
						URLEncoder.encode(getVerifier().getVerifier(), "UTF-8"));
				
			}else{
				//possibly verified the request without verifier needed
				Log.d(TAG, "Retreiving Access Token with Request Token");
				getOAuthProvider().retrieveAccessToken(getOAuthConsumer(), getRequestToken().getRequestToken());
			}
			
			setAccessToken(new OAuthAccessToken(getOAuthConsumer().getToken(),
					getOAuthConsumer().getTokenSecret()));
			Log.d(TAG, "Access Token received: " + getAccessToken().getAccessToken());
		} catch (Exception e) {
			Log.e(TAG, e.toString());
			Log.e(TAG, e.getMessage());
		}
	}

}
